// $codepro.audit.disable
/**
 * package for all the model classes to fit the mvc format
 */
package javamonsters.model;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * The Ship class handles what type of Ship the player currently has.
 * 
 * @author elahurd3
 * @version 1.0
 */
public class Ship implements java.io.Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 3810957377321771860L;
	
	/**
	 * object output stream
	 */
	private ObjectOutputStream out;

	public enum ShipType {
		FLEA,
		
		GNAT,
		
		FIREFLY,
		
		MOSQUITO,
		
		BUMBLEBEE,
		
		BEETLE,
		
		HORNET;
	}
	
	/**
	 * the type of ship
	 */
	private final ShipType shipType;
	
	/**
	 * the name of the ship
	 */
	private String name;
	
	/**
	 * the max cargo a ship can carry
	 */
	private int maxCargo;
	
	/**
	 * a hash map for the cargoContents, with a key-value pair of TradeGood and quantity
	 */
	private final HashMap<TradeGood, Integer> cargoContents;
	
	/**
	 * the current fuel of the ship
	 */
	private int fuel;
	
	/**
	 * the maximum amount of fuel a ship can hold
	 */
	private int maxFuel;
	
	/**
	 * the price of the ship
	 */
	private Integer price;
	
	/**
	 * Constructor for Ship which takes in a Ship type and sets cargo size accordingly
	 * 
	 * @param shipType the type of Ship (i.e. Flea, Gnat, etc.)
	 */
	public Ship(ShipType shipType) {
		this.shipType = shipType;
		
		switch(shipType) {
			case FLEA: maxCargo = 15; 
				fuel = 20; 
				name = "Flea";
			    maxFuel = 20; 
			    price = 400;
			break;
			case GNAT: maxCargo = 20;
				fuel = 14; 
				name = "Gnat";
			    maxFuel = 14; 
			    price = 1000;
			break;
			case FIREFLY: maxCargo = 25; 
				fuel = 17; 
				name = "Firefly";
				maxFuel = 17; 
			    price = 2000;
			break;
			case MOSQUITO: maxCargo = 30;
				fuel = 13; 
				name = "Mosquito";
			    maxFuel = 13;
			    price = 4000;
			break;
			case BUMBLEBEE: maxCargo = 35;
				fuel = 15; 
				name = "Bumblebee";
			    maxFuel = 15; 
			    price = 5000;
			break;
			case BEETLE: maxCargo = 40;
				fuel = 14; 
				name = "Beetle"; 
			    maxFuel = 14; 
			    price = 7500;
			break;
			case HORNET: maxCargo = 45; 
				fuel = 16; 
				name = "Hornet";
			    maxFuel = 16; 
			    price = 8000;
			break;
			default: maxCargo = 15; 
				fuel = 20; 
				name = "Flea";
				maxFuel = 20; 
				price = 400;
		}
		cargoContents = new HashMap<TradeGood, Integer>(maxCargo);
	}
	
	/**
	 * Add cargo to the ship
	 * @param good TradeGood to be added
	 * @param quantity the quantity of the good to be added
	 */
	//TODO: change the hard-coded 1 to be quantity, and implement buying more than one TradeGood at a time
	public void addCargo(TradeGood good, Integer quantity) {
		if(cargoContents.size() + 1 < maxCargo) {
			if(cargoContents.containsKey(good)) {
				cargoContents.put(good, cargoContents.get(good) + 1);
			}
			
			else {
				cargoContents.put(good, 1);
			}
			
		}
		
	}

	/**
	 * Remove a TradeGood object from the cargo hull of the ship
	 * @param good TradeGood to be removed
	 * @param quantity the quantity of the good
	 */
	public void removeCargo(TradeGood good, Integer quantity) {
		if (cargoContents.containsKey(good)) {
			final Integer oldQuantity = cargoContents.get(good);
			if (oldQuantity != 0) {
				cargoContents.put(good, oldQuantity - quantity);
			}
		} else {
			return;
		}
	}
	
	/**
	 * Gets a HashMap of the cargo contents
	 * @return a HashMap of the cargo
	 */
	public Map<TradeGood, Integer> getCargoContents() {
		return cargoContents;
	}
	
	/**
	 * Getter for shipType, what type of ship the player currently has
	 * 
	 * @return string for type of ship player has
	 */
	public ShipType getShipType() {
		return shipType;
	}
	
	/**
	 * Getter for max cargo capacity
	 * 
	 * @return the max cargo capacity
	 */
	public int getMaxCargo() {
		return maxCargo;
	}
	
	/**
	 * @return returns the amount of fuel currently left
	 */
	public int getFuel() {
		return fuel;
	}
	
	/**
	 * @param fuel the current fuel
	 */
	public void setFuel(int fuel) {
		this.fuel = fuel;
	}
	
	/**
	 * @return the type of ship as a String
	 */
	public String toString() {
		return name;
	}
	
	/**
	 * @return returns the maxFuel of the ship
	 */
	public int getMaxFuel() {
		return maxFuel;
	}
	
	/**
	 * @return returns the price of the ship
	 */
	public Integer getPrice() {
		return price;
	}
	
	/**
	 * writes this object to a save file
	 * 
	 * @param filename the name of the file to be written to
	 * @throws IOException
	 */
	public void writeObject(String filename) throws IOException {
		try {
			out = new ObjectOutputStream(new FileOutputStream(filename + ".dat"));
			out.writeObject(this);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.close();
		}
	}

	/**
	 * @param selectedShip the selected ship
	 * @return returns a boolean which determines whether or not the 
	 * selectedShip is the same as the current ship
	 */
	public boolean isSameShip(Ship selectedShip) {
		return this.name.equals(selectedShip.name);
	}
}
